package com.leet.code.simple_array;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: WYG
 * @time: 2020/12/27 9:56
 */

public class ShiftGrid {
    public List<List<Integer>> shiftGrid(int[][] grid, int k) {
        //行列式的行数和列数
        int m = grid.length;
        int n = grid[0].length;
        //新建中间临时数组
        int[][] resArray = new int[m][n];
        //当k是矩阵元素数量的倍数时做转换不会改变元素的位置,当不是倍数时才会改变位置
        if (k % (m * n) != 0) {
            //改变元素的位置
            for (int a = 0; a < k % (m * n); a++) {
                for (int i = 0; i < m; i++) {
                    for (int j = 1; j < n; j++) {
                        resArray[i][j] = grid[i][j - 1];
                    }
                    for (int x = 1; x < m; x++) {
                        resArray[x][0] = grid[x - 1][n - 1];
                    }
                    resArray[0][0] = grid[m - 1][n - 1];
                }
                //将改变位置后的元素赋值给原grid,以便于下次正确的循环
                for (int i = 0; i < m; i++) {
                    for (int j = 0; j < n; j++) {
                        grid[i][j] = resArray[i][j];
                    }
                }
            }
        } else {
            //k = a * (m * n)时不需要改变数组,直接将原数组赋值给中间数组即可
            resArray = grid;
        }
        //根据结果数组构造结果list
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            List<Integer> temp = new ArrayList<>();
            for (int j = 0; j < n; j++) {
                temp.add(resArray[i][j]);
            }
            res.add(temp);
        }
        return res;
    }

    //
    public List<List<Integer>> one_shiftGrid(int[][] grid, int k) {
        for (;k > 0; k--) {

            int previous = grid[grid.length - 1][grid[0].length - 1];
            for (int row = 0; row < grid.length; row++) {
                for (int col = 0; col < grid[0].length; col++) {
                    int temp = grid[row][col];
                    grid[row][col] = previous;
                    previous = temp;
                }
            }
        }

        // Copy the grid into a list for returning.
        List<List<Integer>> result = new ArrayList<>();
        for (int[] row : grid) {
            List<Integer> listRow = new ArrayList<>();
            result.add(listRow);
            for (int v : row) listRow.add(v);
        }

        return result;
    }

    public List<List<Integer>> two_shiftGrid(int[][] grid, int k) {

        int numCols = grid[0].length;
        int numRows = grid.length;

        // Setup the 2d list.
        List<List<Integer>> newGrid = new ArrayList<>();
        for (int row = 0; row < numRows; row++) {
            List<Integer> newRow = new ArrayList<>();
            newGrid.add(newRow);
            for (int col = 0; col < numCols; col++) {
                newRow.add(0);
            }
        }

        for (int row = 0; row < numRows; row++) {
            for (int col = 0; col < numCols; col++) {
                int newCol = (col + k) % numCols;
                int wrapAroundCount = (col + k) / numCols;
                int newRow = (row + wrapAroundCount) % numRows;
                newGrid.get(newRow).set(newCol, grid[row][col]);
            }
        }

        return newGrid;
    }
}
